#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <map>
using std::cout;
using std::cerr;
using std::endl;
using std::vector;
using std::set;
using std::map;
using std::string;
using std::ifstream;
using std::istringstream;


class TextQuery
{
public:
    TextQuery(int capacity){
        _lines.reserve(capacity);
    }

	//读取文件，处理内容，将需要的信息
    void readFile(const string & filename){
        ifstream ifs(filename);
        if(!ifs){
            cerr << "ifstream open file failed" << endl;
            return;
        }

        string line;
        int lineNumber = 1;
        while(getline(ifs,line)){
            //读一行，就把这行的内容先保存到vector
            _lines.push_back(line);
            
            //对读取的一行内容进行处理
            dealLine(line);

            istringstream iss(line);
            string word;
            while(iss >> word){
                //统计单词出现的次数
                ++_dict[word];

                //统计单词出现的行号
                _wordNumbers[word].insert(lineNumber);
            }
            ++lineNumber;
        }
        ifs.close();
    }

    void dealLine(string & line){
        //不应该直接舍弃与符号连在一起的单词
        //而且如果先拆分为单词再处理，可能将多个单词合为一个
        //所以直接对一行内容进行处理
        for(auto & ch : line){
            if(!isalpha(ch)){
                ch = ' ';
            }else if(isupper(ch)){
                ch = tolower(ch);
            }
        }
    }

    //查找单词
    void query(const string & word){
        cout << "------------------------" << endl;
        int count = _dict[word];
        cout << word << " occurs " << count 
            << (count > 1 ? " times. " : " time. " ) 
            << endl;

        //set<int>
        auto lineset = _wordNumbers[word];
        for(auto & num : lineset){
            cout << "(line " << num << ") "
                << _lines[num - 1] << endl;
        }

    }
private:
	//把每一行的原始信息存储下来
	vector<string> _lines;
    //单词和行号
	map<string, set<int> > _wordNumbers;
    //单词和词频
	map<string, int> _dict;
};

void test0(){
    TextQuery tq(107);
    tq.readFile("china_daily.txt");
    tq.query("chinese");
}

int main(void){
    test0();
    return 0;
}
